﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using DailyDiet.Models;
using DailyDiet.Services.Constant;
using Xamarin.Essentials;
using Xamarin.Forms;

namespace DailyDiet.Services.Impl
{
    /// <summary>
    /// 推荐餐食推荐实现类
    /// </summary>
    public class NotificationService : INotificationService {

        public INotificationManager _notificationManager;

        public INotificationManager NotificationManager =>
            _notificationManager ?? (_notificationManager =
                DependencyService.Get<INotificationManager>());

        private IPreferenceStorage _preference;
        private IGetRecService _getRecService;
        public async Task SetNotification(string mealTime) {
            int pendingId =
                NotificationConstant.MealTimesKeyToPendingID[mealTime];
            string notificationKey =
                NotificationConstant.MealTimesKeyToNotificationKey[mealTime];
            //判断时候已经设置今天的的通知
            DateTime notificationDeadTime = _preference.Get(notificationKey,
                NotificationConstant.DefaultTime);
            if (notificationDeadTime > DateTime.Now) {
                return;
            }
            
            runSubThread(mealTime,notificationKey,pendingId);
        }

/* 删除定时通知使用场景
 * 当用户在通知发送之前自己填写了今日午餐记录，就不需要再定时发通知了。
 * 也就是他饭都吃了，就不要用推荐了。这事就调用deleteNotification删除
 * 一个预先设置好的通知
 */
        /// <summary>
        /// 删除一个定时通知
        /// </summary>
        /// <param name="mealTime"></param>
        public void DeleteNotification(string mealTime) {
            int pendingId =
                NotificationConstant.MealTimesKeyToPendingID[mealTime];
            NotificationManager?.DeleteNotification(pendingId);
        }

        /// <summary>
        /// 注意时间应该
        /// </summary>
        /// <param name="dateTime"></param>
        /// <returns></returns>
        public string GetMealTimeByDatetime(DateTime dateTime) {
            DateTime time = NotificationServiceConstant.BaseDate
                .AddHours(dateTime.Hour).AddMinutes(dateTime.Minute)
                .AddSeconds(dateTime.Second);
            foreach (var key in NotificationServiceConstant.BeginAndEndTimeOfMealtimes.Keys) {
                var (begin,end) = NotificationServiceConstant.BeginAndEndTimeOfMealtimes[key];
                if (time > begin && time < end) {
                    return key;
                }
            }

            return GetRecServiceConstant.BREAKFAST;
        }

        /// <summary>
        /// 调用子函数的internal函数
        /// </summary>
        /// <param name="mealTime"></param>
        /// <param name="notificationKey"></param>
        /// <param name="pendingId"></param>
        internal void runSubThread(string mealTime, string notificationKey, int pendingId) {
            Task.Run(async () =>
                await SetNotificationSubThreadFunc(mealTime, notificationKey,
                    pendingId));
        }

        /// <summary>
        /// 设置通知子线程方法
        /// </summary>
        /// <param name="mealTimes"></param>
        /// <param name="notificationKey"></param>
        /// <param name="pendingId"></param>
        /// <returns></returns>
        private async Task SetNotificationSubThreadFunc(string mealTimes, string notificationKey, int pendingId) {
            string chineseMealTime =
                NotificationConstant.MealTimesKeyToChinese[mealTimes];
            string dietStr = "";
            string title = "";
            string message = "";
            List<List<Diet>> recList =
                await _getRecService.GetDietRecAsync(mealTimes);
            if (recList == null || recList.Count == 0) {
                return;
            }
            foreach (var diet in recList[0]) {
                dietStr += diet.Name;
            }

            title = chineseMealTime + "推荐以为您准备OK";
            message = "瞧瞧，瞧瞧。我们为您推荐了什么牛马套餐：" + dietStr;
            
            NotificationManager?.SendNotification(title, message, pendingId);

            DateTime deadTime = Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM-dd"))
                .AddDays(1);

            _preference.Set(notificationKey,deadTime);
        }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="preferenceStorage"></param>
        /// <param name="getRecService"></param>
        public NotificationService(
            IPreferenceStorage preferenceStorage,
            IGetRecService getRecService)
        {
            _preference = preferenceStorage;
            _getRecService = getRecService;
        }
        
    }

    public static class NotificationConstant{
/*
 *key，用于存储到偏好的存储的额时候，判断这一餐是否已经设置notification
 *
 */
        public const string BreakfastNotificationKey = nameof(NotificationConstant) + nameof(BreakfastNotificationKey);
        public const string LunchNotificationKey = nameof(NotificationConstant) + nameof(LunchNotificationKey);
        public const string DinnerNotificationKey = nameof(NotificationConstant) + nameof(DinnerNotificationKey);


        public static readonly DateTime DefaultTime = new DateTime(1970, 1, 1);

        /// <summary>
        /// 餐次到转换为NotificationKey
        /// </summary>
        public static Dictionary<string, string> MealTimesKeyToNotificationKey =
            new Dictionary<string, string> {
                {GetRecServiceConstant.BREAKFAST,BreakfastNotificationKey},
                {GetRecServiceConstant.LUNCH,LunchNotificationKey},
                {GetRecServiceConstant.DINNER,DinnerNotificationKey}
            };

        public static Dictionary<string, int> MealTimesKeyToPendingID =
            new Dictionary<string, int> {
                {GetRecServiceConstant.BREAKFAST,1232},
                {GetRecServiceConstant.LUNCH,1523},
                {GetRecServiceConstant.DINNER,1722}
            };

        public static Dictionary<string, string> MealTimesKeyToChinese =
            new Dictionary<string, string> {
                {GetRecServiceConstant.BREAKFAST,"早餐"},
                {GetRecServiceConstant.LUNCH,"午餐"},
                {GetRecServiceConstant.DINNER,"晚餐"}
            };
    }
}
